home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / c / hce.lha / HCE / LibSource / clib / Misc / src / lmath.a < prev    next >
Encoding:
Text File  |  1992-09-02  |  4.5 KB  |  266 lines

  1. * Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2. *
  3. * Permission is granted to anyone to use this software for any purpose
  4. * on any computer system, and to redistribute it freely, with the
  5. * following restrictions:
  6. * 1) No charge may be made other than reasonable charges for reproduction.
  7. * 2) Modified versions must be clearly marked as such.
  8. * 3) The authors are not responsible for any harmful consequences
  9. *    of using this software, even if they result from defects in it.
  10. *
  11. *
  12. * Modified by Detlef Wuerkner for AMIGA
  13. * Changed assembler directives to MOTOROLA format,
  14. * Other changes marked with TETISOFT
  15. *
  16. * 15-01-91 TetiSoft
  17. * Changed saving of D3 in A2 to saving D3 on Stack since we don't want
  18. * either D3 nor A2 destroyed. Also D2 is now saved, since only D0,D1,A0,A1
  19. * are allowed scratch registers for Amiga libraries and so I decided the
  20. * compiler should behave in the same manner.
  21. *
  22. * 16-01-91 TetiSoft
  23. * Since I found out that HCC uses A2 for Structure Assignments and D2 for
  24. * Data Shifts (ASL etc), I re-changed the last changes. Only D3 has to be
  25. * saved since it could contain a register variable.
  26. *
  27. * 20-05-91 TetiSoft
  28. * A2 is now saved since it is a register variable (structure assignments are
  29. * now done via A6)
  30. *
  31. * From the Hcc.lib by Detlef Wurkner, Placed here by Jason Petty.
  32.  
  33.     XDEF    ldiv
  34.     XDEF    lmul
  35.     XDEF    lrem
  36.     XDEF    ldivu
  37.     XDEF    lmulu
  38.     XDEF    lremu
  39.  
  40.     CODE
  41.  
  42. ldiv:
  43.     move.l    4(a7),d0
  44.     bpl    ld1
  45.     neg.l    d0
  46. ld1:
  47.     move.l    8(a7),d1
  48.     bpl    ld2
  49.     neg.l    d1
  50.     eor.b    #$80,4(a7)
  51. ld2:
  52.     bsr    i_ldiv        /* d0 = d0/d1 */
  53.     tst.b    4(a7)
  54.     bpl    ld3
  55.     neg.l    d0
  56. ld3:
  57.     rts
  58.  
  59. lmul:
  60.     move.l    4(a7),d0
  61.     bpl    lm1
  62.     neg.l    d0
  63. lm1:
  64.     move.l    8(a7),d1
  65.     bpl    lm2
  66.     neg.l    d1
  67.     eor.b    #$80,4(a7)
  68. lm2:
  69.     bsr    i_lmul        /* d0 = d0*d1 */
  70.     tst.b    4(a7)
  71.     bpl    lm3
  72.     neg.l    d0
  73. lm3:
  74.     rts
  75.  
  76. lrem:
  77.     move.l    4(a7),d0
  78.     bpl    lr1
  79.     neg.l    d0
  80. lr1:
  81.     move.l    8(a7),d1
  82.     bpl    lr2
  83.     neg.l    d1
  84. lr2:
  85.     bsr    i_ldiv        /* d1 = d0%d1 */
  86.     move.l    d1,d0
  87.     tst.b    4(a7)
  88.     bpl    lr3
  89.     neg.l    d0
  90. lr3:
  91.     rts
  92.  
  93. ldivu:
  94.     move.l    4(a7),d0
  95.     move.l    8(a7),d1
  96.     bsr    i_ldiv
  97.     rts
  98.  
  99. lmulu:
  100.     move.l    4(a7),d0
  101.     move.l    8(a7),d1
  102.     bsr    i_lmul
  103.     rts
  104.  
  105. lremu:
  106.     move.l    4(a7),d0
  107.     move.l    8(a7),d1
  108.     bsr    i_ldiv
  109.     move.l    d1,d0
  110.     rts
  111.  
  112. * A in d0, B in d1, return A*B in d0
  113. i_lmul:
  114.  
  115. ;    move.l    d3,a2        /* save d3 */
  116.     move.l    d3,-(sp)    /* save d3 */
  117.  
  118.     move.w    d1,d2
  119.     mulu    d0,d2        /* d2 = Al * Bl */
  120.  
  121.     move.l    d1,d3
  122.     swap    d3
  123.     mulu    d0,d3        /* d3 = Al * Bh */
  124.  
  125.     swap    d0
  126.     mulu    d1,d0        /* d0 = Ah * Bl */
  127.  
  128.     add.l    d3,d0        /* d0 = (Ah*Bl + Al*Bh) */
  129.     swap    d0
  130.     clr.w    d0        /* d0 = (Ah*Bl + Al*Bh) << 16 */
  131.  
  132.     add.l    d2,d0        /* d0 = A*B */
  133.  
  134. ;    move.l    a2,d3        /* restore d3 */
  135.     move.l    (sp)+,d3    /* restore d3 */
  136.  
  137.     rts
  138.  
  139. *A in d0, B in d1, return A/B in d0, A%B in d1
  140. i_ldiv:
  141.     tst.l    d1
  142.     bne    nz1
  143.  
  144. *    divide by zero
  145.     divu    #0,d0        /* cause trap */
  146.     move.l    #$80000000,d0
  147.     move.l    d0,d1
  148.     rts
  149. nz1:
  150.  
  151. ;    move.l    d3,a2        /* save d3 */
  152.     move.l    d3,-(sp)    /* save d3 */
  153.  
  154.     cmp.l    d1,d0
  155.     bhi    norm
  156.     beq    is1
  157. *    A<B, so ret 0, rem A
  158.     move.l    d0,d1
  159.     clr.l    d0
  160.  
  161. ;    move.l    a2,d3        /* restore d3 */
  162.     move.l    (sp)+,d3    /* restore d3 */
  163.  
  164.     rts
  165. *    A==B, so ret 1, rem 0
  166. is1:
  167.     moveq.l    #1,d0
  168.     clr.l    d1
  169.  
  170. ;    move.l    a2,d3        /* restore d3 */
  171.     move.l    (sp)+,d3    /* restore d3 */
  172.  
  173.     rts
  174. *    A>B and B is not 0
  175. norm:
  176.     cmp.l    #1,d1
  177.     bne    not1
  178. *    B==1, so ret A, rem 0
  179.     clr.l    d1
  180.  
  181. ;    move.l    a2,d3        /* restore d3 */
  182.     move.l    (sp)+,d3    /* restore d3 */
  183.  
  184.     rts
  185. *  check for A short (implies B short also)
  186. not1:
  187.     cmp.l    #$ffff,d0
  188.     bhi    slow
  189. *  A short and B short -- use 'divu'
  190.     divu    d1,d0        /* d0 = REM:ANS */
  191.     swap    d0        /* d0 = ANS:REM */
  192.     clr.l    d1
  193.     move.w    d0,d1        /* d1 = REM */
  194.     clr.w    d0
  195.     swap    d0
  196.  
  197. ;    move.l    a2,d3        /* restore d3 */
  198.     move.l    (sp)+,d3    /* restore d3 */
  199.  
  200.     rts
  201. * check for B short
  202. slow:
  203.     cmp.l    #$ffff,d1
  204.     bhi    slower
  205. * A long and B short -- use special stuff from gnu
  206.     move.l    d0,d2
  207.     clr.w    d2
  208.     swap    d2
  209.     divu    d1,d2        /* d2 = REM:ANS of Ahi/B */
  210.     clr.l    d3
  211.     move.w    d2,d3        /* d3 = Ahi/B */
  212.     swap    d3
  213.  
  214.     move.w    d0,d2        /* d2 = REM << 16 + Alo */
  215.     divu    d1,d2        /* d2 = REM:ANS of stuff/B */
  216.  
  217.     move.l    d2,d1
  218.     clr.w    d1
  219.     swap    d1        /* d1 = REM */
  220.  
  221.     clr.l    d0
  222.     move.w    d2,d0
  223.     add.l    d3,d0        /* d0 = ANS */
  224.  
  225. ;    move.l    a2,d3        /* restore d3 */
  226.     move.l    (sp)+,d3    /* restore d3 */
  227.  
  228.     rts
  229. *    A>B, B > 1
  230. slower:
  231.     move.l    #1,d2
  232.     clr.l    d3
  233. moreadj:
  234.     cmp.l    d0,d1
  235.  
  236. ; CHANGED BY TETISOFT
  237. ; which instruction is that ?
  238. ; I hope I replaced it with the right one...
  239. ;    bhs    adj
  240.     BHI    adj
  241.  
  242.     add.l    d2,d2
  243.     add.l    d1,d1
  244.     bpl    moreadj
  245. * we shifted B until its >A or sign bit set
  246. * we shifted #1 (d2) along with it
  247. adj:
  248.     cmp.l    d0,d1
  249.     bhi    ltuns
  250.     or.l    d2,d3
  251.     sub.l    d1,d0
  252. ltuns:
  253.     lsr.l    #1,d1
  254.     lsr.l    #1,d2
  255.     bne    adj
  256. * d3=answer, d0=rem
  257.     move.l    d0,d1
  258.     move.l    d3,d0
  259.  
  260. ;    move.l    a2,d3        /* restore d3 */
  261.     move.l    (sp)+,d3    /* restore d3 */
  262.  
  263.     rts
  264.  
  265.     END
  266.